import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
import { message } from 'antd';
import { getCurrentUser } from '@/services/user';

interface User {
  userId: number;
  username: string;
}

interface AuthContextType {
  user: User | null;
  setUser: (user: User | null) => void;
  loading: boolean;
  isAuthenticated: boolean;
  login: (data: { user: any; token: string }) => void;
  logout: () => void;
  refreshUserInfo: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

// 先定义函数，再使用它们
// 刷新用户信息的函数
const useAuthProvider = () => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  // 刷新用户信息
  const refreshUserInfo = async () => {
    // 首先检查是否有token，没有token说明用户未登录，不需要调用用户信息接口
    const token = localStorage.getItem('token');
    if (!token) {
      console.log('未检测到登录令牌，跳过获取用户信息');
      return;
    }
    
    try {
      const userInfo = await getCurrentUser();
      if (userInfo && userInfo.id) {
        setUser({
          userId: Number(userInfo.id),
          username: userInfo.username || '用户',
        });
      }
    } catch (error) {
      // 获取用户信息失败，可能是token无效
      console.error('获取用户信息失败:', error);
    }
  };

  // 刷新用户令牌
  const refreshUserToken = async () => {
    try {
      const token = localStorage.getItem('token');
      if (!token) return;

      const response = await fetch('/api/user/refresh-token', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`
        }
      });

      const data = await response.json();
      if (data.code === 200) {
        localStorage.setItem('token', data.data.token);
        console.log('令牌已刷新');
      }
    } catch (error) {
      console.error('刷新令牌失败:', error);
    }
  };

  // 检查令牌是否即将过期 (7天内)
  const checkTokenExpiry = () => {
    const token = localStorage.getItem('token');
    if (!token) return;

    try {
      // 从JWT中解析过期时间
      const payloadBase64 = token.split('.')[1];
      const payload = JSON.parse(atob(payloadBase64));
      
      // 获取过期时间 (exp是Unix时间戳，单位是秒)
      const expTime = payload.exp * 1000; // 转换为毫秒
      const currentTime = Date.now();
      
      // 如果令牌将在7天内过期，尝试刷新
      if ((expTime - currentTime) < 7 * 24 * 60 * 60 * 1000) {
        refreshUserToken();
      }
    } catch (error) {
      console.error('解析令牌失败:', error);
    }
  };

  // 登录函数
  const login = (data: { user: any; token: string }) => {
    const { user, token } = data;
    if (user && user.id) {
      // 保存token
      localStorage.setItem('token', token);
      // 更新用户状态
      setUser({
        userId: Number(user.id),
        username: user.username || '用户',
      });
    }
  };

  // 登出函数
  const logout = () => {
    localStorage.removeItem('token');
    localStorage.removeItem('user');
    setUser(null);
  };

  useEffect(() => {
    // 从localStorage加载用户
    const storedUser = localStorage.getItem('user');
    if (storedUser) {
      try {
        setUser(JSON.parse(storedUser));
      } catch (e) {
        localStorage.removeItem('user');
      }
    }

    // 尝试获取当前用户信息
    refreshUserInfo();

    // 登录过期事件处理
    const handleAuthExpired = () => {
      setUser(null);
      message.error('登录已过期，请重新登录');
    };
    
    window.addEventListener('auth:expired', handleAuthExpired);

    // 定期检查令牌是否即将过期
    checkTokenExpiry();
    const tokenCheckInterval = setInterval(checkTokenExpiry, 24 * 60 * 60 * 1000); // 每天检查一次

    setLoading(false);

    return () => {
      clearInterval(tokenCheckInterval);
      window.removeEventListener('auth:expired', handleAuthExpired);
    };
  }, []);

  // 更新localStorage中的用户信息
  useEffect(() => {
    if (user) {
      localStorage.setItem('user', JSON.stringify(user));
    } else {
      localStorage.removeItem('user');
    }
  }, [user]);

  return {
    user,
    setUser,
    loading,
    isAuthenticated: !!user,
    login,
    logout,
    refreshUserInfo
  };
};

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const auth = useAuthProvider();
  
  // 使用useMemo优化性能
  const contextValue = useMemo(() => auth, [
    auth.user,
    auth.loading,
    auth.isAuthenticated
  ]);

  return <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
} 